﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Forms;
using excel = Microsoft.Office.Interop.Excel;

namespace PersonaLibrary.ViewModel
{
    public class BaseExcelVM : BaseViewModel<View.ExcelView.ExcelView>
    {
        private excel.Workbook _openedBook;
        private RelayCommand _openFileCommand;
        private RelayCommand _commitOperationCommand;
        private excel._Application _app;
        private readonly ObservableCollection<string> _workSheetNames = new ObservableCollection<string>();
        private readonly ObservableCollection<string> _fileNames;
        private string _selectedFileName;
        private string _selectedWorkSheet;
        private string _offset = "A1";
        private int _allCount;
        private int _currentCount;
        private bool _isLoading;

        public BaseExcelVM()
        {
            if (Properties.Settings.Default.LastOpenedFiles == null)
            {
                Properties.Settings.Default.LastOpenedFiles = new System.Collections.Specialized.StringCollection();
                _fileNames = new ObservableCollection<string>(Properties.Settings.Default.LastOpenedFiles.Cast<string>());
            }
            else
                _fileNames = new ObservableCollection<string>(Properties.Settings.Default.LastOpenedFiles.Cast<string>());
            RisePropertyChanged("FileNames");
            _app = new excel.Application();
        }

        protected excel.Workbook OpenedBook
        {
            get
            {
                return _openedBook;
            }
            private set
            {
                _openedBook = value;
                RisePropertyChanged("OpenedBook");
            }
        }

        protected excel.Worksheet OpenedWorksheet
        {
            private set; get;
        }

        public bool IsLoading
        {
            get { return _isLoading; }
            protected set
            {
                _isLoading = value; 
                RisePropertyChanged("IsLoading");
            }

        }

        public int AllCount
        {
            protected set 
            { 
                _allCount = value;
                RisePropertyChanged("AllCount");
            }
            get { return _allCount; }
        }

        public int CurrentCount
        {
            protected set
            {
                _currentCount = value; 
                RisePropertyChanged("CurrentCount");
            }
            get { return _currentCount; }
        }

        public RelayCommand OpenFileCommand
        {
            get
            {
                if (_openFileCommand == null) _openFileCommand = new RelayCommand(param => OpenFile(), pram => true);
                return _openFileCommand;
            }
        }

        public RelayCommand CommitOperationCommand
        {
            get
            {
                if (_commitOperationCommand == null) _commitOperationCommand = new RelayCommand(param => CommitOperation(), CanCommitOperation);
                return _commitOperationCommand;
            }
        }

        public ObservableCollection<string> WorkSheetNames
        {
            get
            {
                return _workSheetNames;
            }
        }

        public ObservableCollection<string> FileNames
        {
            get
            {
                return _fileNames;
            }
        }

        public string SelectedFileName
        {
            set
            {
                _selectedFileName = value;
                RisePropertyChanged("SelectedFileName");
                onSelectedNameChanged();
            }
            get
            {
                return _selectedFileName;
            }
        }

        public string SelectedWorkSheet
        {
            get
            {
                return _selectedWorkSheet;
            }
            set
            {
                _selectedWorkSheet = value;
                RisePropertyChanged("SelectedWorkSheet");
                onWorksheetChanged();
            }
        }

        public string Offset
        {
            get
            {
                return _offset;
            }
            set
            {
                _offset = value;
                RisePropertyChanged("Offset");
            }
        }

    	protected bool ExcelVisible
    	{
    		set { _app.Visible = value; }
			get { return _app.Visible; }
    	}

		protected bool ExcelUserControl
		{
			set { _app.UserControl = value; }
			get { return _app.UserControl; }
		}

		protected void ExcelClose()
		{
			_app.Application.Quit();
			_app.Quit();

			System.Runtime.InteropServices.Marshal.ReleaseComObject(_app);
			_app = null;
			GC.Collect();
			GC.WaitForPendingFinalizers();
		}

        protected virtual void CommitOperation()
        {
            _app.Visible = true;
            _app.UserControl = true;
            View.Close();
        }
		
        protected virtual bool CanCommitOperation(object arg)
        {
            if (OpenedBook == null)
                return false;
            return true;
        }

        private void onWorksheetChanged()
        {
            foreach (excel.Worksheet sheet in OpenedBook.Worksheets)
                if (sheet.Name == SelectedWorkSheet)
                    OpenedWorksheet = sheet;
        }

        private void onSelectedNameChanged()
        {
            OpenedBook = _app.Workbooks.Open(SelectedFileName);

            _workSheetNames.Clear();
            foreach (excel.Worksheet sheet in OpenedBook.Worksheets)
                _workSheetNames.Add(sheet.Name);
        }

        private void OpenFile()
        {             
            OpenFileDialog oFD = new OpenFileDialog();

            if (oFD.ShowDialog() == DialogResult.OK)
            {
                _fileNames.Add(oFD.FileName);
                if (Properties.Settings.Default.LastOpenedFiles.Count > Properties.Settings.Default.MaxOpenedFiles ) Properties.Settings.Default.LastOpenedFiles.RemoveAt(0);
                Properties.Settings.Default.LastOpenedFiles.Add(oFD.FileName);
                Properties.Settings.Default.Save();
                SelectedFileName = oFD.FileName;
            }
        }
    }
}
